import React, { forwardRef, useCallback, useImperativeHandle, useState } from 'react'
import { useAntdTable } from 'ahooks'
import { Badge, Icon, Modal, Popconfirm, message } from 'antd'
import ProcessSetting from '../ProcessSetting'
import ProcessRunModal from '../ProcessRun/ProcessRunModal'
import VersionCopyModal from './VersionCopyModal'
import request from '@/utils/request'
import SlickTable from '@/components/SlickTable'
import Space from '@/components/Space'
import IconLink from '@/components/IconLink'
import useModal from '@/hooks/UseModal'
import { getCurrentTenantId, getUsername } from '@/utils/user'
import { routeTo } from '@/utils/router'

function getTableData({ current, pageSize, processId }) {
  return request.post('/process/pageVersions', {
    data: {
      current,
      pageSize,
      processId,
    },
  })
}

export const VersionStateMap = {
  0: <Badge status="warning" text="未生效" />,
  1: <Badge status="success" text="生效中" />,
  2: <Badge status="error" text="失效" />,
}

function VersionPageTable({ data }, ref) {
  const { processId, processName } = data

  const {
    tableProps: { pagination, loading: tableLoading, ...restTableProps },
    refresh,
  } = useAntdTable(
    (query) => {
      return getTableData({ ...query, processId })
    },
    {
      defaultPageSize: 5,
      refreshDeps: [processId],
    },
  )

  const [loading, setLoading] = useState(false)

  useImperativeHandle(ref, () => ({
    refresh,
  }))

  /**
   * 失效版本
   */
  const invalidVersion = useCallback(
    (versionId) => {
      setLoading(true)
      request
        .post(`/process/invalidVersion?versionId=${versionId}`)
        .then(() => refresh())
        .finally(() => setLoading(false))
    },
    [refresh],
  )

  /**
   * 删除版本
   */
  const deleteVersion = useCallback(
    (versionId) => {
      setLoading(true)
      request
        .post(`/process/deleteVersion?versionId=${versionId}`)
        .then(() => refresh())
        .finally(() => setLoading(false))
    },
    [refresh],
  )

  /**
   * 生效版本
   */
  const validVersion = useCallback(
    (processId, versionId) => {
      Modal.confirm({
        title: '确定要生效当前版本吗？',
        content: '注意：此操作将会使当前生效中的版本失效！',
        onOk: () => {
          setLoading(true)
          request
            .post(`/process/validVersion?processId=${processId}&versionId=${versionId}`)
            .then(() => refresh())
            .finally(() => setLoading(false))
        },
      })
    },
    [refresh],
  )

  /**
   * 解锁版本
   */
  const unlockVersion = (processId, versionId) => {
    setLoading(true)
    request
      .post(`/process/releaseLock?processId=${processId}&versionId=${versionId}`)
      .then(refresh)
      .finally(() => setLoading(false))
  }

  /**
   * 上锁版本
   */
  const lockVersion = (processId, versionId) => {
    setLoading(true)
    request
      .post(`/process/tryLock?processId=${processId}&versionId=${versionId}`)
      .then(refresh)
      .finally(() => setLoading(false))
  }

  /**
   * 复制版本
   */
  const copyVersion = useCallback(
    (processId, versionId) => {
      setLoading(true)
      request
        .post(`/process/copyVersion?processId=${processId}&versionId=${versionId}`)
        .then(() => refresh())
        .finally(() => setLoading(false))
    },
    [refresh],
  )

  function exportVersion(versionId) {
    const formElement = document.createElement('form')
    formElement.style.display = 'display:none'
    formElement.method = 'post'
    formElement.action = `v1/process/exportVersionData?processId=${processId}&versionId=${versionId}&tenantId=${getCurrentTenantId()}`
    formElement.target = '_blank'
    document.body.appendChild(formElement)
    formElement.submit()
    document.body.removeChild(formElement)
  }

  const {
    hideModal: hideSettingModal,
    showModal: showSettingModal,
    visible: settingModalVisible,
    data: settingModalData,
  } = useModal()

  const {
    hideModal: hideCopyModal,
    showModal: showCopyModal,
    visible: copyModalVisible,
    data: copyModalData,
  } = useModal()

  const columns = [
    {
      title: '版本号',
      dataIndex: 'versionNumber',
    },
    {
      title: '版本状态',
      dataIndex: 'versionState',
      render: text => VersionStateMap[text],
    },
    {
      title: '被谁锁定',
      dataIndex: 'lockedBy',
      render: lockedBy =>
        lockedBy && (
          <>
            <Icon
              type="lock"
              className={lockedBy === getUsername() ? 'text-info' : 'text-danger'}
            />
            <span style={{ marginLeft: 4 }}>{lockedBy}</span>
          </>
        ),
    },
    {
      title: '创建时间',
      dataIndex: 'createDate',
    },
    {
      title: '创建人',
      dataIndex: 'createStaff',
    },
    {
      title: '更新时间',
      dataIndex: 'updateDate',
    },
    {
      title: '更新人',
      dataIndex: 'updateStaff',
    },
    {
      title: '版本操作',
      width: '550px',
      render: (_text, record) => {
        const locked = record.lockedBy
        const isLockedByMe = locked && locked === getUsername()
        const isLockedByOther = locked && locked !== getUsername()

        const { versionId, versionState, versionNumber } = record
        const showCopyBtn = versionState === 1 || versionState === 2
        const showValidBtn = versionState === 0 && !isLockedByOther
        const showUnlockBtn = isLockedByMe
        const showDeleteBtn = (versionState === 0 || versionState === 2) && !isLockedByOther
        const showInvalidBtn = versionState === 1
        const showDrawBtn = versionState === 0 && !isLockedByOther
        const showExportBtn = versionState === 1

        const showLockBtn = showValidBtn && !locked

        return (
          <Space divider="vertical">
            {showCopyBtn
              ? (
              <IconLink icon="copy" onClick={() => showCopyModal({ processId, versionId })}>
                复制
              </IconLink>
                )
              : null}
            {showValidBtn
              ? (
              <IconLink
                className="text-success"
                iconFont="icon-valid"
                onClick={() => validVersion(processId, versionId)}
              >
                生效
              </IconLink>
                )
              : null}
            {showLockBtn && (
              <IconLink
                className="text-warning"
                icon="lock"
                onClick={() => lockVersion(processId, versionId)}
              >
                上锁
              </IconLink>
            )}
            {showUnlockBtn && (
              <IconLink
                className="text-success"
                icon="unlock"
                onClick={() => unlockVersion(processId, versionId)}
              >
                解锁
              </IconLink>
            )}
            {showDeleteBtn
              ? (
              <Popconfirm
                title={`确定要删除版本【${versionNumber}】吗`}
                onConfirm={() => {
                  if (pagination.total === 1) {
                    message.warn('至少要有一个版本！')
                    return
                  }
                  deleteVersion(versionId)
                }}
              >
                <IconLink className="text-danger" icon="delete">
                  删除
                </IconLink>
              </Popconfirm>
                )
              : null}
            {showInvalidBtn
              ? (
              <IconLink
                className="text-warning"
                onClick={() => invalidVersion(versionId)}
                iconFont="icon-invalid"
              >
                失效
              </IconLink>
                )
              : null}
            {showDrawBtn
              ? (
              <IconLink
                icon="edit"
                onClick={() =>
                  routeTo(
                    `/flow/${processId}?versionId=${versionId}&tabName=${encodeURIComponent(
                      processName,
                    )}`,
                  )
                }
              >
                流程绘制
              </IconLink>
                )
              : null}

            <IconLink
              icon="eye"
              onClick={() =>
                routeTo(
                  `/flow/${processId}?versionId=${versionId}&readOnly=true&tabName=${encodeURIComponent(
                    processName,
                  )}`,
                )
              }
            >
              流程预览
            </IconLink>
            <IconLink
              icon="setting"
              onClick={() =>
                showSettingModal({
                  processId,
                  versionId,
                  readOnly: versionState !== 0 || isLockedByOther,
                })
              }
            >
              运行设置
            </IconLink>
            <ProcessRunModal processId={processId} versionId={versionId}>
              <IconLink icon="play-circle">流程试跑</IconLink>
            </ProcessRunModal>
            {showExportBtn && (
              <IconLink icon="cloud-download" onClick={() => exportVersion(versionId)}>
                配置导出
              </IconLink>
            )}
          </Space>
        )
      },
    },
  ]

  return (
    <>
      <SlickTable
        loading={tableLoading || loading}
        rowKey="versionId"
        columns={columns}
        data={{ pagination }}
        {...restTableProps}
      />
      {settingModalVisible && (
        <ProcessSetting
          data={settingModalData}
          visible={settingModalVisible}
          onCancel={hideSettingModal}
        />
      )}
      {copyModalVisible && (
        <VersionCopyModal
          data={copyModalData}
          visible={copyModalVisible}
          onCancel={() => {
            hideCopyModal()
            refresh()
          }}
        />
      )}
    </>
  )
}

export default forwardRef(VersionPageTable)
